import os
import sys
import logging
from concurrent import futures

from motor import MotorClient

from tornado.web import Application
from tornado.httpserver import HTTPServer
from tornado.ioloop import IOLoop
from tornado.gen import coroutine
from tornado.options import define, parse_command_line, options

import handlers

define("port", default=8888, help="run on the given port", type=int)
define("mongo_host", default="mongodb://127.0.0.1:27017",
       help="app database host")
define("mongo_db", default="qy", help="app database name")
parse_command_line()

settings = {
    "template_path": os.path.join(os.path.dirname(__file__), "templates"),
    "static_path": os.path.join(os.path.dirname(__file__), "static"),
    "download": os.path.join(os.path.dirname(__file__), "download"),
    "cookie_secret": "s3cr3tk3y",
    "cookie_name": 'user_info',
    "xsrf_cookies": True,
    "intranet": True,
    "login_url": "/auth/signin",
    "thread_pool": futures.ThreadPoolExecutor(4),
    "session": {
        "driver": "redis",
        "driver_settings": {
            "host": "localhost",
                    "port": 6379,
            "db": 1
        },
        "force_persistence": False,
        "cache_driver": True,
        "cookie_config": {
            "httponly": True
        },
    },
    "default_handler_class": handlers.NotFoundHandler,
    "debug": True,
}

# 数据库
try:
    client = MotorClient(options.mongo_host)
    database = client[options.mongo_db]
    settings["database"] = database
except:
    logging.error("cannot connect mongodb")
    sys.exit(0)

handlers = [
    (r'^/', 'handlers.site.IndexHandler'),
    (r'^/gf', 'handlers.site.GaoFenHandler'),
    (r'^/admin', 'handlers.admin.IndexHandler'),
    (r'^/admin/signin', 'handlers.admin.SigninHandler'),
    (r'^/admin/signout', 'handlers.admin.SignoutHandler'),
    (r'^/admin/data', 'handlers.data.ListHandler'),
    (r'^/admin/data/([a-f0-9]{24})', 'handlers.data.DetailAdminHandler'),
    (r'^/data/form', 'handlers.data.FormHandler'),
    (r'^/data/form_meta',
     'handlers.data.MetaFormHandler'),
    (r'^/admin/data/publish',
     'handlers.data.PublishHandler'),
    (r'^/admin/data/close/([a-f0-9]{24})',
     'handlers.data.CloseHandler'),
    (r'^/admin/data/modify',
     'handlers.data.ModifyHandler'),
    (r'^/admin/data_meta/modify',
     'handlers.data.ModifyMetaHandler'),
    (r'^/admin/data_meta/create',
     'handlers.data.CreateMetaHandler'),
    (r'^/admin/apply', 'handlers.apply.ListHandler'),
    (r'^/admin/apply/([a-f0-9]{24})', 'handlers.apply.DetailAdminHandler'),
    (r'^/admin/apply/refuse/([a-f0-9]{24})',
     'handlers.apply.RefuseAdminHandler'),
    (r'^/admin/apply/reset/([a-f0-9]{24})',
     'handlers.apply.ResetAdminHandler'),
    (r'^/admin/apply/accept/([a-f0-9]{24})',
     'handlers.apply.AcceptAdminHandler'),
    (r'^/admin/app', 'handlers.apps.ListAdminHandler'),
    (r'^/admin/app/([a-f0-9]{24})', 'handlers.apps.DetailAdminHandler'),
    (r'^/auth/signin', 'handlers.auth.SigninHandler'),
    (r'^/auth/signup', 'handlers.auth.SignupHandler'),
    (r'^/auth/userinfo', 'handlers.auth.UserinfoHandler'),
    (r'^/auth/signout', 'handlers.auth.SignoutHandler'),
    (r'^/home', 'handlers.site.HomeHandler'),
    (r'^/data', 'handlers.data.IndexHandler'),
    (r'^/data/detail/([a-f0-9]{24})', 'handlers.data.DetailHandler'),
    (r'^/apply/my', 'handlers.apply.MyHandler'),
    (r'^/apply/detail/([a-f0-9]{24})', 'handlers.apply.DetailHandler'),
    (r'^/apply/form/([a-f0-9]{24})', 'handlers.apply.FormHandler'),
    (r'^/apply/drop/([a-f0-9]{24})', 'handlers.apply.DropHandler'),
    (r'^/app/my', 'handlers.apps.MyHandler'),
    (r'^/app/detail/([a-f0-9]{24})', 'handlers.apps.DetailHandler'),
    (r'^/records/my', 'handlers.records.MyHandler'),
    (r'^/data/download', 'handlers.data.DownloadHandler'),
    (r'^/download/(.*)', 'handlers.download.DownloadHandler',
     {'path': settings['download']}),
]


class App(Application):

    def __init__(self):
        super(App, self).__init__(handlers, **settings)


def main():
    http_server = HTTPServer(App(), xheaders=True)
    http_server.listen(options.port)

    logging.info('Server running on http://127.0.0.1:%d' % (options.port))
    IOLoop.instance().start()

if __name__ == '__main__':
    main()
